home *** CD-ROM | disk | FTP | other *** search
- unit mwStringStream;
-
- interface
-
- uses
- SysUtils, Classes;
-
- procedure MoveNoOverlap(const Source; var Dest; count : Integer );
-
- type
- TmwStringStream = class(TStream)
- private
- FDataString: string;
- FPosition: Integer;
- FSize: Integer;
- function GetDataString: string;
- procedure Grow(Value: Integer);
- procedure SetCapacity(const NewCapacity: Integer);
- function GetCapacity: Integer;
- procedure SetDataString(const Value: string);
- function GetAsPChar: PChar;
- protected
- procedure SetSize(NewSize: Longint); override;
- public
- constructor Create; overload;
- constructor Create(const AString: string); overload;
- procedure Clear;
- procedure LoadFromStream(Stream: TStream);
- procedure LoadFromFile(const FileName: string);
- function Read(var Buffer; Count: Longint): Longint; override;
- function ReadString(Count: Longint): string;
- function ReadWideString(Count: Longint): WideString;
- procedure SaveToStream(Stream: TStream);
- procedure SaveToFile(const FileName: string);
- function Seek(Offset: Longint; Origin: Word): Longint; override;
- function Write(const Buffer; Count: Longint): Longint; override;
- procedure WriteString(const AString: string);
- procedure WriteWideString(const AWideString: WideString);
- property AsPChar: PChar read GetAsPChar;
- property Capacity: Integer read GetCapacity write SetCapacity;
- property DataString: string read GetDataString write SetDataString;
- end;
-
- implementation
-
- procedure MoveNoOverlap(const Source; var Dest; count : Integer );
- asm
- PUSH ESI
- PUSH EDI
-
- MOV ESI,EAX
- MOV EDI,EDX
-
- MOV EAX,ECX
-
- SAR ECX,2
-
- REP MOVSD
-
- MOV ECX,EAX
- AND ECX,03H
- REP MOVSB
-
- POP EDI
- POP ESI
- end;
-
- { TmwStringStream }
-
- procedure TmwStringStream.Clear;
- begin
- FDataString:= '';
- FPosition:= 1;
- FSize:= 0;
- end;
-
- constructor TmwStringStream.Create;
- begin
- inherited Create;
- FPosition:= 1;
- end;
-
- constructor TmwStringStream.Create(const AString: string);
- begin
- inherited Create;
- FDataString:= AString;
- FSize:= Length(FDataString);
- FPosition:= 1;
- end;
-
- function TmwStringStream.GetAsPChar: PChar;
- begin
- Result:= PChar(GetDataString);
- end;
-
- function TmwStringStream.GetCapacity: Integer;
- begin
- Result:= Length(FDataString);
- end;
-
- function TmwStringStream.GetDataString: string;
- begin
- if FSize <> Capacity then SetLength(FDataString, FSize);
- Result:= FDataString;
- end;
-
- procedure TmwStringStream.Grow(Value: Integer);
- var
- Delta: Integer;
- begin
- Delta := Capacity div 10;
- SetCapacity(Capacity + Value + Delta);
- end;
-
- procedure TmwStringStream.LoadFromFile(const FileName: string);
- var
- Stream: TStream;
- begin
- Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
- try
- LoadFromStream(Stream);
- finally
- Stream.Free;
- end;
- end;
-
- procedure TmwStringStream.LoadFromStream(Stream: TStream);
- var
- Count: Longint;
- begin
- Stream.Position := 0;
- Count := Stream.Size;
- SetSize(Count);
- if Count <> 0 then Stream.ReadBuffer(Pointer(FDataString)^, Count);
- end;
-
- function TmwStringStream.Read(var Buffer; Count: Integer): Longint;
- begin
- Result := FSize - FPosition;
- if Result > Count then Result := Count;
- MoveNoOverlap(Pointer(Integer(FDataString) + FPosition - 1)^, Buffer, Result);
- Inc(FPosition, Result);
- end;
-
- function TmwStringStream.ReadString(Count: Integer): string;
- var
- Readed: Integer;
- begin
- SetLength(Result, Count);
- Readed := Read(Pointer(Result)^, Count);
- if Readed <> Count then SetLength(Result, Readed);
- end;
-
- function TmwStringStream.ReadWideString(Count: Integer): WideString;
- var
- Readed: Integer;
- begin
- SetLength(Result, Count);
- Readed := Read(Pointer(Result)^, Count*2);
- if Readed <> Count*2 then SetLength(Result, Readed div 2);
- end;
-
- procedure TmwStringStream.SaveToFile(const FileName: string);
- var
- Stream: TStream;
- begin
- Stream := TFileStream.Create(FileName, fmCreate);
- try
- SaveToStream(Stream);
- finally
- Stream.Free;
- end;
- end;
-
- procedure TmwStringStream.SaveToStream(Stream: TStream);
- begin
- if FSize <> 0 then Stream.WriteBuffer(Pointer(FDataString)^, FSize);
- end;
-
- function TmwStringStream.Seek(Offset: Integer; Origin: Word): Longint;
- begin
- case Origin of
- soFromBeginning: FPosition := Offset;
- soFromCurrent: FPosition := FPosition + Offset;
- soFromEnd: FPosition := FSize - Offset;
- end;
- if FPosition > FSize +1 then
- FPosition := FSize +1
- else if FPosition < 1 then FPosition := 1;
- Result := FPosition;
- end;
-
- procedure TmwStringStream.SetCapacity(const NewCapacity: Integer);
- begin
- if NewCapacity <> Capacity then
- begin
- SetLength(FDataString, NewCapacity);
- if FSize > NewCapacity then SetSize(NewCapacity);
- end;
- end;
-
- procedure TmwStringStream.SetDataString(const Value: string);
- begin
- FDataString:= Value;
- FPosition:= 1;
- FSize:= Length(Value);
- end;
-
- procedure TmwStringStream.SetSize(NewSize: Integer);
- begin
- fSize:= NewSize;
- if Capacity < NewSize then SetCapacity(NewSize);
- if FPosition > NewSize +1 then FPosition := NewSize +1;
- end;
-
- function TmwStringStream.Write(const Buffer; Count: Integer): Longint;
- begin
- Result := Count;
- if FPosition + Count > Capacity then Grow(Count);
- MoveNoOverlap(Buffer, Pointer(Integer(FDataString) + FPosition - 1)^, Result);
- Inc(FPosition, Result);
- Inc(FSize, Result);
- end;
-
- procedure TmwStringStream.WriteString(const AString: string);
- begin
- Write(Pointer(AString)^, Length(AString));
- end;
-
- procedure TmwStringStream.WriteWideString(const AWideString: WideString);
- begin
- Write(Pointer(AWideString)^, Length(AWideString)*2);
- end;
-
- end.
-
-